09 sample_vpad-analog.hsp

sample\ 09 sample_vpad-analog.hsp

#include "hsp3dish.as"

#include "mod_layerbutton.hsp"

#packopt xsize 480
#packopt ysize 800

	screen 0,480,800
	// HSP3Dish.js用データフォルダ設定
	info_os = sysinfo(0)
	if instr(info_os,0,"Emscripten")>=0 : mm_dir="" : else : mm_dir="data/"
	
	// 画像読み込み
	celload mm_dir+"pad.png", -1
	cel_pad = stat : celdiv cel_pad,128,128, 64,64
	celload mm_dir+"nub.png", -1
	cel_nub = stat : celdiv cel_nub,64,64, 32,32
	celload mm_dir+"btn.png", -1
	cel_btn = stat : celdiv cel_btn,64,64
	celload mm_dir+"btn2x.png", -1
	cel_btn2x = stat : celdiv cel_btn2x,128,128
	celload mm_dir+"bean.png", -1
	cel_bean = stat : celdiv cel_bean,64,42, 32,21
	
	pxConL = 100             ; コントローラ表示位置の中心X座標
	pyConL = ginfo_sy-100    ; コントローラ表示位置の中心Y座標
	szConL = 1.0             ; コントローラのサイズ倍率
	zurizuri = 1             ; スティックを範囲外まで動かしたら本体を追従させるオプション (逆方向に操作する際、常に一定のスライド量で反対側まで操作できます)
	gosub *create_analogCon  ; アナログスティック作成

	pxConR = ginfo_sx-60
	pyConR = ginfo_sy-70
	szConR = 1.0
	gosub *create_btnCon   ; ボタン作成

	myPx = double(ginfo_sx/2) : myPy = double(ginfo_sy/2)  ; 自機位置
	pausemx = -ginfo_sx  ; 表示初回だけ画面外に飛ばす(描画幅計測のため)
// メインループ
repeat
	redraw 0 : color 255,255,255 : boxf : color : font msgothic,16
	myPx = limitf(myPx+(analogx*15),0,ginfo_sx-16)
	myPy = limitf(myPy+(analogy*15),0,ginfo_sy-16)
	pos myPx, myPy : mes "●"
	if shotPy>0 : pos shotPx, shotPy : mes "▲" : shotPy-=16
	if bombSz>0 : bombSz+=50 : boxf bmPx-bombSz,bmPy-bombSz,bmPx+bombSz,bmPy+bombSz : if bombSz>800 : bombSz=0
	if gamePause : gmode 3,,,100 : boxfao 0,0,480,800 : color 255 : pos (ginfo_sx-pausemx)/2,350 : mes "Pause" : if pausemx<0 : pausemx=ginfo_mesx
	redraw 1
	await 1000/60
loop
stop

// アナログスティック作成
*create_analogCon
	pos pxConL-(szConL*64), pyConL-(szConL*64)
	layerbutton szConL*128,szConL*128, 0,0 {
		laybtn_settings 0,4,1+4  ; 設定 : ボタン外からスライドしてもクリック + ボタンを押しても消さない
		laybtn_hitarea -1, objlayer_size_x/2,objlayer_size_y/2, objlayer_size_x  ; 円形ヒットエリア
		if lparam == objlayer_cmddraw {
			if layerbtn_clickx!=-1 && layerbtn_clicky!=-1 && gamePause==0 {  ; クリック/タッチ中 (ポーズ時は操作させない)
				layerbtn_clickx_ = double(layerbtn_clickx) + zrzrx
				layerbtn_clicky_ = double(layerbtn_clicky) + zrzry
				rr = double(objlayer_size_x)/2  ; スティックが動く範囲の半径
				dx = -layerbtn_clickx_ + layerbtn_mousex
				dy = -layerbtn_clicky_ + layerbtn_mousey
				_dist = dx*dx + dy*dy
				if _dist > rr*rr {
					dist = sqrt(_dist)
					layerbtn_mousex_ = double(dx * rr) / dist + layerbtn_clickx_
					layerbtn_mousey_ = double(dy * rr) / dist + layerbtn_clicky_
					if zurizuri : zrzrx-=layerbtn_mousex_-layerbtn_mousex : zrzry-=layerbtn_mousey_-layerbtn_mousey
				}else{
					layerbtn_mousex_ = double(layerbtn_mousex)
					layerbtn_mousey_ = double(layerbtn_mousey)
				}
				// パッドのアナログ値
				analogx = (layerbtn_mousex_ - (layerbtn_clickx_))*2 / objlayer_size_x
				analogy = (layerbtn_mousey_ - (layerbtn_clicky_))*2 / objlayer_size_y
				// 表示用の補正
				layerbtn_mousex_ -= objlayer_size_x/2
				layerbtn_mousey_ -= objlayer_size_y/2
				layerbtn_clickx_ -= objlayer_size_x/2
				layerbtn_clicky_ -= objlayer_size_y/2
			}else {
				zrzrx=0.0 : zrzry=0.0
				analogx=0.0 : analogy=0.0
				// 表示用の補正
				layerbtn_mousex_ = 0.0
				layerbtn_mousey_ = 0.0
				layerbtn_clickx_ = layerbtn_mousex_
				layerbtn_clicky_ = layerbtn_mousey_
			}
			// pad, nub 描画
			laybtn_ezcel cel_pad, 1,,,,,,, layerbtn_clickx_, layerbtn_clicky_, szConL,szConL  ; ezcelの裏技 : 第9引数から ボタン画像ずらし量, 強制倍率 を指定できる
			laybtn_ezcel cel_nub, 1,,,,,,, layerbtn_mousex_, layerbtn_mousey_, szConL,szConL
		}
		return
	}
	return

// ボタン作成
*create_btnCon
	; A (shot)
	pos pxConR-(szConR*48), pyConR-(szConR*48)
	layerbutton szConR*96,szConR*96, 0,1 {
		laybtn_settings 0,4+8,1+4  ; 設定 : 同グループ押下中ならボタン外からスライドしてもクリック + ボタンを押しても消さない
		laybtn_hitarea -1, objlayer_size_x/2,objlayer_size_y/2, objlayer_size_x  ; 円形ヒットエリア
		if lparam == objlayer_cmddraw {
			font msgothic,24,1 : color 200,200,200
			laybtn_ezcel cel_btn2x,0, "Shot"
			if gamePause : return  ; ポーズ中は操作させない
			if (layerbtn_stat & LAYBTN_PRESS_IN)!=0 && layerbtn_cnt == 0 {
				if shotPy <= 0 : shotPx = myPx : shotPy = myPy
			}
		}
		return
	}
	; B (bomb)
	pos pxConR-(szConR*120), pyConR-(szConR*16)
	layerbutton szConR*64,szConR*64, 1,1 {
		laybtn_settings 0,4+8,1+4  ; 設定 : 同グループ押下中ならボタン外からスライドしてもクリック + ボタンを押しても消さない
		laybtn_hitarea -1, objlayer_size_x/2,objlayer_size_y/2, objlayer_size_x  ; 円形ヒットエリア
		if lparam == objlayer_cmddraw {
			font msgothic,16,1 : color 200,200,200
			laybtn_ezcel cel_btn,0, "Bomb"
			if gamePause : return  ; ポーズ中は操作させない
			if (layerbtn_stat & LAYBTN_PRESS_IN)!=0 && layerbtn_cnt == 0 {
				if bombSz <= 0 : bmPx = myPx : bmPy = myPy : bombSz = 50
			}
		}
		return
	}
	; menu
	pos pxConR+(szConR*-5), pyConR-(szConR*90)
	layerbutton szConR*64,szConR*42, 2,1 {
		laybtn_settings 0,2,1+4  ; 設定 : マウスクリックで即決定 + ボタンを押しても消さない
		laybtn_hitarea -3, objlayer_size_x/2,objlayer_size_y/2, objlayer_size_x,objlayer_size_y, 20.0/180.0*M_PI  ; 長方形(角度付き)ヒットエリア
		if lparam == objlayer_cmddraw {
			font msgothic,20 : color 200,200,200
			pos objlayer_axis_x+objlayer_size_x/2, objlayer_axis_y+objlayer_size_y/2
			switch (layerbtn_stat|1^1)  ; _SELECTED状態を除去して分岐 [(layerbtn_stat & $FFFE)でもOK]
			case LAYBTN_FOCUS_IN : id_celdiv = 1 : swbreak
			case LAYBTN_PRESS_IN : id_celdiv = 2 : swbreak
			default : id_celdiv = 0
			swend
			celput cel_bean, id_celdiv, szConR,szConR, 20.0/180.0*M_PI
			laybtn_mes "≡",0, 1,1
			if layerbtn_stat == LAYBTN_PRESS_IN_SELECTED {
				gamePause = 1 - gamePause  ; ポーズ切り替え
			}
		}
		return
	}
	return

#module
#deffunc boxfao int ax, int ay, int bx, int by, int ox, int oy
	pdx=ax+ox,bx+ox,bx+ox,ax+ox
	pdy=ay+oy,ay+oy,by+oy,by+oy
	gsquare -1,pdx,pdy
	return
#global